package com.hskn.hss.utils;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.hskn.hss.core.utils.spring.SpringUtils;
import com.hskn.hss.module.common.service.impl.CommonServiceImpl;
import com.hskn.hss.module.dataBigscreen.vo.UserTest;
import net.sf.json.JSONObject;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.util.Objects;

public class BeanChangeUtil<T> {

    public static <T> void main(String[] args) {
        UserTest u1 = new UserTest("报警", true, "张三");
        UserTest u2 = new UserTest("违规", false, "张三");
        BeanChangeUtil<T> t = new BeanChangeUtil<>();
        String str = t.contrastObj(u1, u2);
        if (str.equals("")) {
            System.out.println("未有改变");
        } else {
            System.out.println(str);
        }
    }

    @SuppressWarnings({ "unchecked", "rawtypes" })
    public String contrastObj(Object oldBean, Object newBean) {
        StringBuilder str = new StringBuilder();
        T pojo1 = (T) oldBean;
        T pojo2 = (T) newBean;
        try {
            // 通过反射获取类的类类型及字段属性
            Class clazz = pojo1.getClass();
            Field[] fields = clazz.getDeclaredFields();
            int i = 1;
            for (Field field : fields) {
                // 排除序列化属性
                if ("serialVersionUID".equals(field.getName())) {
                    continue;
                }
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), clazz);
                // 获取对应属性值
                Method getMethod = pd.getReadMethod();
                Object o1 = getMethod.invoke(pojo1);
                Object o2 = getMethod.invoke(pojo2);
                if (o1 == null || o2 == null) {
                    continue;
                }
                if (!o1.toString().equals(o2.toString())) {
                    str.append(i + "、字段名称:" + field.getName() + "由“" + o1 + "”改为“" + o2 + "”;");
                    i++;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return str.toString();
    }

    /**
     * 比对两个对象的差异
     * @param tableName 表名
     * @param idKey     主键
     * @param oldBean   历史数据
     * @param newBean   新数据
     * @param isCompare 是否比较
     * @return
     */
    public String contrastJSONObj(String tableName, String idKey, JSONObject oldBean, JSONObject newBean, Boolean isCompare) {

        StringBuilder str = new StringBuilder();
        newBean.keySet().forEach(t->{
            //获取字段注释
            String columnName = com.hskn.hss.core.utils.StringUtils.isEmpty(String.valueOf(t).trim())?String.valueOf(t).trim():String.valueOf(t).trim().replaceAll("[A-Z]", "_$0").toLowerCase();
            String columnComment = SpringUtils.getBean(CommonServiceImpl.class).getColumnComment(tableName, columnName);
            if (com.hskn.hss.core.utils.StringUtils.isEmpty(columnComment)){
                columnComment = SpringUtils.getBean(CommonServiceImpl.class).getColumnComment(tableName, String.valueOf(t).trim());
            }
            System.out.println(columnComment);
            if (StringUtils.isNotEmpty(columnComment)){
                if (!isCompare){
                    if (Objects.nonNull(oldBean.get(t)) && Objects.nonNull(newBean.get(t)) && !oldBean.get(t).equals(newBean.get(t)) && !String.valueOf(oldBean.get(t)).equals(String.valueOf(newBean.get(t)))
                            && (StringUtils.isNotEmpty(oldBean.get(t)) && StringUtils.isNotEmpty(newBean.get(t))) && !idKey.equals(t)) {
                        str.append("修改了<" + columnComment + ">;");
                    }
                } else {
                    if (Objects.nonNull(oldBean.get(t)) && Objects.nonNull(newBean.get(t)) && !oldBean.get(t).equals(newBean.get(t)) && !String.valueOf(oldBean.get(t)).equals(String.valueOf(newBean.get(t)))
                            && (StringUtils.isNotEmpty(oldBean.get(t)) && StringUtils.isNotEmpty(newBean.get(t))) && !idKey.equals(t)) {

                        if (Tools.isDateTime(String.valueOf(oldBean.get(t))) && Tools.isDateTime(String.valueOf(newBean.get(t)))){

                            DateTime oldDateTime;
                            DateTime newDateTime;

                            if (Tools.isDate(String.valueOf(oldBean.get(t)))){
                                oldDateTime = DateUtil.parseDate(String.valueOf(oldBean.get(t)));
                            } else {
                                oldDateTime = DateUtil.parseDateTime(String.valueOf(oldBean.get(t)));
                            }

                            if (Tools.isDate(String.valueOf(newBean.get(t)))){
                                newDateTime = DateUtil.parseDate(String.valueOf(newBean.get(t)));
                            } else {
                                newDateTime = DateUtil.parseDateTime(String.valueOf(newBean.get(t)));
                            }

                            if (oldDateTime.compareTo(newDateTime) != 0){
                                str.append("<" + columnComment + ">由“" + oldDateTime + "”改为“" + newDateTime + "”;");
                                System.out.println(str);
                            }
                        } else if (String.valueOf(oldBean.get(t)).indexOf(".") > -1 ){
                            int i = String.valueOf(oldBean.get(t)).indexOf(".");
                            int length = String.valueOf(oldBean.get(t)).substring(i+1).length();
                            if (length == 2 && new BigDecimal(String.valueOf(oldBean.get(t))).compareTo(new BigDecimal(String.valueOf(newBean.get(t)))) != 0){
                                str.append("<" + columnComment + ">由“" + new BigDecimal(String.valueOf(oldBean.get(t))) + "”改为“" + new BigDecimal(String.valueOf(newBean.get(t))) + "”;");
                                System.out.println(str);
                            }
                        } else {
                            str.append("<" + columnComment + ">由“" + oldBean.get(t) + "”改为“" + newBean.get(t) + "”;");
                            System.out.println(str);
                        }
                    }
                }
            }
        });
        String message = str.toString();
        //这样就去掉可最后一个符号
        if (message.length() >= 1){
            message = message.substring(0,message.length() -1);
        }
        return message;
    }

}